/**
 * 
 * author: luchyx for riaevolution.com ®
 * date: 08/11/2006
 * 
 * This class provide the functionality or shor-cuts to control UI's components
 * in corresponding states.
 * for example if you are building a text editor.
 * If the state is the dafult state. You may wish to enable certain buttons.
 * For example, if the document is empty the current State is new Docs.
 * If the document is saving into the database you may put the state controller in pending, like could mean UI disabled.
 * You can add each UI component to respond for any state in diferent way.
 * Example here an Image uploader form.
 * formStateController.add(submitBtn, false, StateController.FORM_INVALID);
 * formStateController.add(imageUploader, false, StateController.FORM_INVALID);
 * //this will disable all items if the form is invalid 
 * formStateController.currentState = StateController.FORM_INVALID;
 **/
package com.riaevolution.components
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.core.UIComponent;

	public class StateController extends EventDispatcher
	{
		private var curState:String;
		private var hash_states:Object;
		public function StateController()
		{
			//TODO: implement function
			super();
			hash_states = new Object();
		}
		public function set currentState(n:String):void{
			//if(curState == n) return;
			curState = n;
			invalidate();
		}
		public function get currentState():String {
			return curState;
		}
		public function toogleAll():void{
			getState(currentState).toogleAll();
		}
		public function enableAll():void{
			getState(currentState).enableAll();
		}
		public function disableAll():void{
			getState(currentState).disableAll();
		}
		private function invalidate():void{
			if(getState(currentState) == null) return;
			getState(currentState).invalidate();
		}
		public function addState(name:String,usealpha:Boolean = true):void{
			if(name == null){
				throw new Error("Invalid name for the state");	
			}
			if(hash_states[name] != null){
				throw new Error("This state already exist.");
			}
			var itemsState:StateDescriptor = new StateDescriptor(name,usealpha);
			hash_states[name] = itemsState;
			if(curState == null) {
				curState = name;
			}
		}
		public function getState(name:String):StateDescriptor {
			if(hash_states == null) {
				hash_states = new Object();
			}
			return hash_states[name];
		}
		public function addInState(item:UIComponent,mode:Boolean,state:String):void{
			getState(state).add(item,mode);
		}
		public function removeItem(comp:UIComponent):void{
			/**
			for(var t:int=0; t <= items.length; t++){
				if(items.getItemAt(t).item == comp){
					items.removeItemAt(t);
				}	
			}
			**/
		}
		public function removeAt(n:Number):void{
			//items.removeItemAt(n);
		}
		public function get collection():Object {
			return hash_states;
		}
		public function set collection(col:Object):void {
			//this.items.source = col;
		}
		public static const NORMAL_STATE:String = "n0";
		public static const SAVE_STATE:String = "n1";
		public static const CANCEL_STATE:String = "n2";
		public static const EDIT_STATE:String = "n3";
		public static const NEW_STATE:String = "n4";
		public static const PENDING_STATE:String = "n5";
		public static const ALL_ENABLED:String = "n6";
		public static const ALL_DISABLED:String = "n7";
	}
}
/**
 * Value Object that hold a component an his state. 
 **/
import mx.core.UIComponent;
class ItemState {
	public var item:UIComponent;
	public var state:Boolean;//enabled/disable
	public function ItemState(me:UIComponent,mestate:Boolean):void{
		item = me;
		state = mestate;
	}
}
/**
 * Acts as a value object also has other funcionality but availables only throw StateController.
 **/
import mx.collections.ArrayCollection;
class StateDescriptor {
	[ArrayElementType("ItemState")]
	private var itemsInState:ArrayCollection;
	private var name:String;
	public  var usealpha:Boolean = true;
	
	public function StateDescriptor(n:String,usea:Boolean=true){
		itemsInState = new ArrayCollection();
		name = n;
		usealpha = usea;
	}
	public function add(item:UIComponent,mode:Boolean):void{
		var its:ItemState = new ItemState(item,mode);
		itemsInState.addItem(its);
	}
	//toogle all UI doing enabled = !enabled;
	public function toogleAll():void{
		for(var t:int=0; t < itemsInState.length; t++){
			var its:ItemState = itemsInState.getItemAt(t) as ItemState;
			its.item.enabled = !its.item.enabled;
			if(usealpha) {
				its.item.alpha = its.item.enabled ? 1:0.2;	
			}
		}	
	}
	//disable all the UI no matter the desired state
	public function disableAll():void{
		for(var t:int=0; t < itemsInState.length; t++){
			var its:ItemState = itemsInState.getItemAt(t) as ItemState;
			its.item.enabled = false;
			if(usealpha) {
				its.item.alpha = 0.2;	
			}
		}	
	}
	/**
	 * Despite the UI state we put in enable=true.
	 * @public
	 * */
	public function enableAll():void{
		for(var t:int=0; t < itemsInState.length; t++){
			var its:ItemState = itemsInState.getItemAt(t) as ItemState;
			its.item.enabled = true;
			if(usealpha) {
				its.item.alpha = 1;	
			}
		}	
	}
	public function invalidate():void{
		for(var t:int=0; t < itemsInState.length; t++){
			var its:ItemState = itemsInState.getItemAt(t) as ItemState;
			its.item.enabled = its.state;
			if(usealpha) {
				its.item.alpha = its.state ? 1:0.2;	
			}
		}
	}
}